package my;

import org.w3c.dom.NodeList;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.HashSet;
import java.util.Set;

public class MySOAPHandler implements SOAPHandler<SOAPMessageContext> {
    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        System.out.println("Handler 被调用！方向: " + (isRequest ? "出站(客户端发送)" : "入站(服务端接收)"));

        try {
            SOAPMessage message = context.getMessage();
            if (message != null) {
                // 打印完整的SOAP消息用于调试
                System.out.println("=== SOAP消息内容 ===");
                message.writeTo(System.out);
                System.out.println("\n===================");

                SOAPHeader header = message.getSOAPHeader();
                if (header != null) {
                    System.out.println("找到SOAP Header");
                    String namespace = "http://my/";

                    // 尝试多种方式查找student元素
                    NodeList studentElements1 = header.getElementsByTagNameNS(namespace, "student");
                    NodeList studentElements2 = header.getElementsByTagName("ns:student");
                    NodeList studentElements3 = header.getElementsByTagName("student");

                    System.out.println("使用命名空间URI查找student元素: " + studentElements1.getLength());
                    System.out.println("使用ns:前缀查找student元素: " + studentElements2.getLength());
                    System.out.println("使用本地名查找student元素: " + studentElements3.getLength());

                    NodeList studentElements = studentElements1.getLength() > 0 ? studentElements1 :
                            (studentElements2.getLength() > 0 ? studentElements2 : studentElements3);

                    if (studentElements.getLength() > 0) {
                        SOAPElement student = (SOAPElement) studentElements.item(0);
                        System.out.println("找到student元素，命名空间: " + student.getNamespaceURI());

                        // 尝试多种方式获取子元素
                        NodeList snoNodes = student.getElementsByTagNameNS(namespace, "sno");
                        NodeList snameNodes = student.getElementsByTagNameNS(namespace, "sname");
                        NodeList timeNodes = student.getElementsByTagNameNS(namespace, "time");

                        // 如果命名空间方式找不到，尝试本地名
                        if (snoNodes.getLength() == 0) {
                            snoNodes = student.getElementsByTagName("sno");
                        }
                        if (snameNodes.getLength() == 0) {
                            snameNodes = student.getElementsByTagName("sname");
                        }
                        if (timeNodes.getLength() == 0) {
                            timeNodes = student.getElementsByTagName("time");
                        }

                        if (snoNodes.getLength() > 0 && snameNodes.getLength() > 0 && timeNodes.getLength() > 0) {
                            String sno = snoNodes.item(0).getTextContent();
                            String sname = snameNodes.item(0).getTextContent();
                            String time = timeNodes.item(0).getTextContent();

                            System.out.println("=== Handler解析到的Header信息 ===");
                            System.out.println("学号: " + sno);
                            System.out.println("姓名: " + sname);
                            System.out.println("时间: " + time);
                            System.out.println("================================");

                            // 关键修改：将Header信息存储到MessageContext中，供ServiceImpl使用
                            // 这是JAX-WS中Handler与Service实现类之间传递数据的标准方式
                            String headerInfo = String.format("学号:%s,姓名:%s,时间:%s", sno, sname, time);
                            context.put("STUDENT_HEADER_INFO", headerInfo);
                            context.setScope("STUDENT_HEADER_INFO", MessageContext.Scope.APPLICATION);

                            // 也可以分别存储各个字段，方便ServiceImpl单独使用
                            context.put("STUDENT_SNO", sno);
                            context.put("STUDENT_SNAME", sname);
                            context.put("STUDENT_TIME", time);
                            context.setScope("STUDENT_SNO", MessageContext.Scope.APPLICATION);
                            context.setScope("STUDENT_SNAME", MessageContext.Scope.APPLICATION);
                            context.setScope("STUDENT_TIME", MessageContext.Scope.APPLICATION);

                            System.out.println("Handler: 已将Header信息存储到MessageContext中");

                        } else {
                            System.out.println("Header中缺少必要的子元素");
                            System.out.println("sno节点数: " + snoNodes.getLength());
                            System.out.println("sname节点数: " + snameNodes.getLength());
                            System.out.println("time节点数: " + timeNodes.getLength());

                            // 打印student的所有子元素用于调试
                            System.out.println("student的子元素:");
                            if (student.hasChildNodes()) {
                                for (int i = 0; i < student.getChildNodes().getLength(); i++) {
                                    System.out.println("  - " + student.getChildNodes().item(i).getNodeName() +
                                            " (命名空间: " + student.getChildNodes().item(i).getNamespaceURI() + ")");
                                }
                            }
                        }
                    } else {
                        System.out.println("未找到student元素");
                        // 打印所有header元素用于调试
                        System.out.println("Header内容:");
                        if (header.hasChildNodes()) {
                            for (int i = 0; i < header.getChildNodes().getLength(); i++) {
                                System.out.println("  - 节点名: " + header.getChildNodes().item(i).getNodeName());
                                System.out.println("  - 命名空间: " + header.getChildNodes().item(i).getNamespaceURI());
                                System.out.println("  - 本地名: " + header.getChildNodes().item(i).getLocalName());
                            }
                        } else {
                            System.out.println("Header没有子节点");
                        }
                    }
                } else {
                    System.out.println("SOAP消息中没有Header");
                }
            } else {
                System.out.println("SOAP消息为空");
            }
        } catch (Exception e) {
            System.err.println("Handler处理异常: " + e.getMessage());
            e.printStackTrace();
        }
        return true; // 返回true继续处理链
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        System.out.println("Handler处理Fault");
        return false;
    }

    @Override
    public void close(MessageContext context) {
        System.out.println("Handler关闭");
    }

    @Override
    public Set<QName> getHeaders() {
        // 声明此Handler可以处理的Header元素
        Set<QName> headers = new HashSet<>();
        headers.add(new QName("http://my/", "student"));
        return headers;
    }
}